home *** CD-ROM | disk | FTP | other *** search
/ Resource Library: Multimedia / Resource Library: Multimedia.iso / maestro / source / timeline / openapps.c < prev    next >
Encoding:
Text File  |  1993-06-15  |  24.7 KB  |  618 lines

  1. /*
  2.  * Copyright (c) 1990, 1991 Stanford University
  3.  *
  4.  * Permission to use, copy, modify, and distribute this software and 
  5.  * its documentation for any purpose is hereby granted without fee, provided
  6.  * that (i) the above copyright notices and this permission notice appear in
  7.  * all copies of the software and related documentation, and (ii) the name
  8.  * Stanford may not be used in any advertising or publicity relating to
  9.  * the software without the specific, prior written permission of
  10.  * Stanford.
  11.  * 
  12.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  13.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  14.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  15.  *
  16.  * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
  17.  * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES
  18.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT
  19.  * ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY,
  20.  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  21.  * SOFTWARE.
  22.  */
  23.  
  24. /* $Header: /Source/Media/collab/TimeLine/RCS/openApps.c,v 1.1 92/01/09 16:26:43 drapeau Exp $ */
  25. /* $Log:    openApps.c,v $
  26.  * Revision 1.1  92/01/09  16:26:43  drapeau
  27.  * Made slight modifications to make code more ANSI-compliant.
  28.  * 
  29.  * Revision 1.0  91/09/30  17:02:09  chua
  30.  * Update to version 1.0
  31.  * 
  32.  * Revision 0.77  91/09/26  18:03:47  chua
  33.  * In OpenAppsInitialize, change the add parameter to load.  When load = 0,
  34.  * the function is being called from the OpenHandler.  If any applications in
  35.  * the current instrument list is not open, it will be launched by calling
  36.  * GetPortFromName.  Only if this fails will the application be muted.
  37.  * 
  38.  * Revision 0.76  91/09/25  13:51:13  chua
  39.  * Changed the instrument field, instInfo, to editInfo.
  40.  * Changed InstrumentInfo to EditInfo.
  41.  * 
  42.  * Revision 0.75  91/09/19  18:32:04  chua
  43.  * Removed the DestroyPortArray statement in OpenAppsInitialize as this causes
  44.  * segmentation fault due to the ports being freed.
  45.  * 
  46.  * Revision 0.74  91/09/19  17:29:01  chua
  47.  * Make sure that variables are initialized properly.  Change formatting slightly,
  48.  * so that (if, for, while) statements with only one statement in them will not have
  49.  * braces.
  50.  * 
  51.  * Revision 0.73  91/09/17  17:17:36  chua
  52.  * In DeleteAppsHandler, reassign the PANEL_CLIENT_DATA of the notes info list
  53.  * to the new positions of those applications which have changed their
  54.  * positions due to the deletion.
  55.  * 
  56.  * Revision 0.72  91/09/16  15:10:42  chua
  57.  * Rewrote the OpenAppsInitialize and UpdateAppsHandler routines so that when doing an
  58.  * update apps application, the notes that are currently on the TimeLine are not erased.
  59.  * The OpenAppsInitialize would also be smart enough to fill in the applications on the
  60.  * existing instrument list with the port numbers of the applications obtained from the
  61.  * Port Manager.
  62.  * 
  63.  * Revision 0.71  91/09/09  14:57:09  chua
  64.  * In OpenAppsInitialize, if the appname is TimeLine, do not include in the instrument list.
  65.  * Previously, if the appname is TimeLine but the hostname is different, it will be
  66.  * included.  This is just a temporary measure.  Once the receiver protocol is implemented
  67.  * in the TimeLine, other TimeLines will be included in the instrument list.
  68.  * 
  69.  * In OpenAppsFindIcon, there was an error in allocating space to appIcon. It should be
  70.  * sizeof (IconData) instead of sizeof(appIcon).
  71.  * 
  72.  * Revision 0.70  91/09/04  15:11:05  chua
  73.  * In OpenAppsFindIcon, if GetAppIcon does not return the proper icon bits,
  74.  * return the unknownIcon.
  75.  * 
  76.  * Revision 0.69  91/08/27  18:18:33  chua
  77.  * In DeleteAppHandler, before doing a DestroySender, check that the 
  78.  * application is still alive.
  79.  * 
  80.  * Revision 0.68  91/08/26  14:22:04  chua
  81.  * Removed the tlFrame->actualApps variable.
  82.  * 
  83.  * Revision 0.67  91/08/22  15:03:32  chua
  84.  * A minor formatting change in line 183.
  85.  * 
  86.  * Revision 0.66  91/08/22  12:10:29  chua
  87.  * In the OpenAppsFindIcon function, before doing a NewSender to check if an application is
  88.  * open, make sure that it was previously open first.
  89.  * 
  90.  * Revision 0.65  91/08/21  16:58:35  chua
  91.  * In OpenAppsFindIcon, send a SenderGetAppIcon message to the application to get
  92.  * its icon.  If this fails, then look in the graphics directory for the icon file.
  93.  * 
  94.  * Revision 0.64  91/08/19  19:20:39  chua
  95.  * In the UpdateAppsHandler, do a DestroySender for the old instrument list nodes.
  96.  * 
  97.  * Revision 0.63  91/08/16  17:02:35  chua
  98.  * In the UpdateAppsHandler, reset the filename to 'untitled'.
  99.  * 
  100.  * Revision 0.62  91/08/08  15:47:49  chua
  101.  * In UpdateAppsHandler, replace return NULL by return item
  102.  * 
  103.  * Revision 0.61  91/08/08  14:27:27  chua
  104.  * In OpenAppsFindIcon, since TimeLineHome now points directly to the graphics directory
  105.  * instead of its parent, make the appropriate changes when trying to find the icon.
  106.  * 
  107.  * Revision 0.60  91/08/05  16:53:27  chua
  108.  * Deleted the RepaintCanvas routine, as it is no longer necessary.  In places where it
  109.  * is called, just call the ScrollToFirstQuarter routine, which will do the necessary
  110.  * repaint as well.
  111.  * 
  112.  * Revision 0.59  91/07/17  16:34:49  chua
  113.  * Reformatted the braces for the switch statements.
  114.  * 
  115.  * Revision 0.58  91/07/17  10:32:21  chua
  116.  * In the OpenAppsFindIcon function, first check if the icon file can be found before
  117.  * attempting to create a server image with it.  This is to prevent a XView error
  118.  * message from appearing if the icon is not found.
  119.  * 
  120.  * Revision 0.57  91/07/09  17:02:17  chua
  121.  * Removed some redundant variables.
  122.  * 
  123.  * Revision 0.56  91/06/26  16:48:09  chua
  124.  * In the OpenAppsInitialize routine, check also that the hostname is not equal to "localhost" in
  125.  * line 134.  This is because the default host is now "localhost".
  126.  * 
  127.  * Revision 0.55  91/06/25  17:52:20  chua
  128.  * Added two new functions, which are the menu handlers for the Show Application and Hide Application
  129.  * menu items found under the Application menu button.
  130.  * 
  131.  * Show Application will move the media editor to the front of the screen, and Hide Application will
  132.  * iconify it.
  133.  * 
  134.  * Revision 0.54  91/06/04  17:37:25  chua
  135.  * Added the copyright comments in the beginning of the file.
  136.  * 
  137.  * Revision 0.53  91/06/04  10:43:53  chua
  138.  * Added a call to UpdateHeader to update the header of the frame whenever
  139.  * there is a change in the status of the change flag.
  140.  * 
  141.  * Revision 0.52  91/06/03  11:12:02  chua
  142.  * Make changes to accomodate multiple documents.  This involves identifying
  143.  * which is the current active window, that is, the one where the last mouse
  144.  * click was done.
  145.  * 
  146.  * Revision 0.51  91/05/28  12:15:18  chua
  147.  * 
  148.  * 
  149.  * Revision 0.50  91/05/24  16:37:22  chua
  150.  * Added the code for the DeleteAppHandler.  Please refer to the comments
  151.  * header for the function on how it works.
  152.  * 
  153.  * Revision 0.49  91/05/23  17:39:07  chua
  154.  * *** empty log message ***
  155.  * 
  156.  * Revision 0.48  91/05/22  16:42:02  chua
  157.  * 
  158.  * 
  159.  * Revision 0.47  91/05/22  13:59:35  chua
  160.  * 
  161.  * 
  162.  * Revision 0.46  91/05/22  11:47:00  chua
  163.  * 
  164.  * 
  165.  * Revision 0.45  91/05/17  16:58:53  chua
  166.  * *** empty log message ***
  167.  * 
  168.  * Revision 0.44  91/05/17  16:58:10  chua
  169.  * *** empty log message ***
  170.  * 
  171.  * Revision 0.43  91/05/17  16:57:08  chua
  172.  * *** empty log message ***
  173.  * 
  174.  * Revision 0.42  1991/04/24  01:10:22  chua
  175.  * In the UpdateAppsHandler,  the section of code dealing with freeing all the instrument nodes is
  176.  * replaced by a call to the FreeInstrumentList function.
  177.  *
  178.  * In the ShowNotesInfoHandler, the call to InitInstInfoWindow is replaced by ShowInfoWindow,
  179.  * since the pop-up window will have already been created (in InstrumentNew) and we only need
  180.  * to bring it up to the front and be visible.
  181.  *
  182.  * Revision 0.41  1991/04/08  21:29:33  chua
  183.  * In the UpdateAppsHandler, when freeing each instrument, destroy the info pop-up window as well if it has been
  184.  * created.
  185.  *
  186.  * A new menu option for the Applications menu button has been added.  This is the ShowNotesInfoHandler
  187.  * function.  This function first checks if an application has been selected.  If so, it will call the
  188.  * InitInstInfoWindow to display the info pop-up window.
  189.  *
  190.  * Revision 0.40  1991/04/01  03:44:52  chua
  191.  * This file contains functions which deal with asking the PortManager for a list of its open applications.
  192.  * The functions are:
  193.  * OpenAppsInitialize - ask the PortManager for a list of open applications and build an instrument list for
  194.  *                      these applications (one application being represented by an instrument).
  195.  * OpenAppsFindIcon - gets the icon file for the application and create a server image for it.  This function
  196.  *                    is called by InstrumentDrawIcon (instrument.c) which does the actual drawing of the
  197.  *                    icon on the screen.
  198.  * UpdateAppsHandler - ask the PortManager for its current list of open applications and reconstruct the
  199.  *                     instrument list of the TimeLine Editor.  This function is used when either some
  200.  *                     applications have died or some new ones were launched since the TimeLine Editor was
  201.  *                     first ran.
  202.  * DeleteAppsHandler - not implemented yet.
  203.  * */
  204.  
  205. static char openappsrcsid[] = "$Header: /Source/Media/collab/TimeLine/RCS/openApps.c,v 1.1 92/01/09 16:26:43 drapeau Exp $";
  206.  
  207. #include "main.h"
  208. #include <sys/stat.h>
  209.  
  210. Instrument     *instHead;                        /* Pointer to the head of the instrument list */
  211. char        TimeLineHost[MAXHOSTNAMELEN];                /* Host from where the TimeLine Editor is launched */
  212.  
  213. /*
  214.  * This function will ask the Port Manager for the list of open applications that is registered with it.
  215.  * With the information from the Port Manager, it will form an instrument list, which is used to store information about the instrument as well as
  216.  * keep track of new notes added to the instrument in future by the user.
  217.  * If an instrument list already exist, an attempt is made to find a match in port number between the apps on the instrument list and those on the list
  218.  * given by the port manager.  If such a match could not be found, check for a match in application name.  If that fails, mute the application on the
  219.  * instrument list that could not be matched.  However, if load = 0, indicating that this function was called from OpenHandler, call 
  220.  * SenderGetPortFromName to launch the application.  Only if this fails will the application be muted.
  221.  * Add the applications on the port manager list that has no equivalent app on the instrument list.
  222.  * The parameter load indicates if unassigned ports should be added to the instrument list.  This is usually desirable, except when opening a file,
  223.  * when we only want to see the apps which existed when the file was saved.  Thus, when opening a file, load = 0.  If load = 0, this will also
  224.  * launch any application in the file that is currently not opened.
  225.  * Called by TimeLineInit (TimeLine.c) and UpdateAppsHandler (openApps.c)
  226.  */
  227. void OpenAppsInitialize(tlFrame, load)
  228.      TimeLineFramePtr tlFrame;
  229.      int load;
  230. {
  231.   int         i, j;
  232.   int         found;
  233.   int        result;
  234.   PortArray     *appsOpen = (PortArray *) NULL;                /* Array to store the list of open applications and their port information */
  235.   PortArray     *appsNew = (PortArray *) NULL;                /* Array to store the a newly opened app launched by GetPortFromName */
  236.   Port        appPort;
  237.   Instrument     *instrument;
  238.   Instrument     *multipleInst;
  239.   int        *portUsed;                        /* Keep track of which port has already been assigned to the instrument list */
  240.   int         count;                            /* Keep track of how many copies of the same app exist in the instrument list */
  241.   
  242.   result = SenderGetOpenApps(tlFrame->TimeLineSender, &appsOpen);   /* Get list of open applications from the PortManager */
  243.   if (result == -1) 
  244.     return;
  245.   portUsed = (int *) malloc (sizeof (int) * appsOpen->numberOfPorts);
  246.   for (i = 0; i < appsOpen->numberOfPorts; i++) 
  247.     portUsed[i] = 0;
  248.   instrument = tlFrame->instHead;
  249.   for (i = 0; i < tlFrame->numberOfApps; i++) 
  250.   {
  251.     j = 0;
  252.     found = 0;
  253.     while (j < appsOpen->numberOfPorts && !found)            /* Check if there is a match in port number */
  254.     {
  255.       if (instrument->port->portNumber == appsOpen->portArray[j].portNumber) 
  256.       {
  257.     found = 1;
  258.     portUsed[j] = 1;
  259.       }
  260.       else
  261.     j ++;
  262.     }
  263.     if (found == 0)                            /* Check if there is a match in application name */
  264.     {
  265.       j = 0;
  266.       while (j < appsOpen->numberOfPorts && !found)            /* Check if there is a match in port number */
  267.       {
  268.     if (strcmp(instrument->port->appName, appsOpen->portArray[j].appName) == 0 && portUsed[j] == 0)
  269.     {
  270.       if ((instrument->sender = NewSender(appsOpen->portArray+j)) != NULL) /* Check if sender to the application can be created */
  271.       {
  272.         if (strcmp(instrument->port->hostName, "App not open") == 0) /* Check if app was previously not open */
  273.         {
  274.           xv_set(instrument->editInfo->MuteChoice, PANEL_VALUE, 0, NULL); /* Unmute the app */
  275.           xv_set(instrument->editInfo->MuteChoice, PANEL_INACTIVE, FALSE, NULL);
  276.         }
  277.         strcpy(instrument->port->hostName, appsOpen->portArray[j].hostName);
  278.         instrument->port->portNumber = appsOpen->portArray[j].portNumber;
  279.         xv_set(instrument->editInfo->HostnameText,            /* Set the hostname on the pop-up window */
  280.            PANEL_LABEL_STRING, instrument->port->hostName, NULL);
  281.         instrument->icon = (Pixmap) xv_get(OpenAppsFindIcon(instrument), /* Get the pixmap image of the icon */
  282.                            SERVER_IMAGE_PIXMAP);
  283.         found = 1;
  284.         portUsed[j] = 1;
  285.       }
  286.       else
  287.         j++;
  288.     }
  289.     else
  290.       j ++;
  291.       }
  292.     }
  293.     if (!found)                                /* Mute the application, as there is no equivalent app checked in */
  294.     {
  295.       result = -1;
  296.       if (load == 0)                            /* Try to launch the application by calling SenderGetPortFromName */
  297.       {
  298.     multipleInst = tlFrame->instHead;
  299.     count = 1;
  300.     while (multipleInst != instrument) 
  301.     {
  302.       if (strcmp(multipleInst->port->appName, instrument->port->appName) == 0)
  303.         count ++;
  304.       multipleInst = multipleInst->next;
  305.     }
  306.     appPort.appName = (char *) malloc (MAXPATHLEN);
  307.     strcpy(appPort.appName, instrument->port->appName);
  308.     appPort.hostName = "localhost";
  309.     result = SenderGetPortFromName(tlFrame->TimeLineSender, &appPort, &appsNew);
  310.     if (result == 0 && appsNew)                    /* Get port is successful */ 
  311.       if (appsNew->numberOfPorts < count)                /* Check if we need to force launch a new application */
  312.       {
  313.         DestroyPortArray(appsNew);
  314.         appPort.hostName = LaunchNewApp;
  315.         result = SenderGetPortFromName(tlFrame->TimeLineSender, &appPort, &appsNew);
  316.       }
  317.     if (result == 0 && appsNew)                    /* Get port is successful */ 
  318.       if (appsNew->numberOfPorts > 0) 
  319.         if ((instrument->sender = NewSender(appsNew->portArray+(count - 1))) != NULL) /* Check if sender to the application can be created */ 
  320.         {
  321.           strcpy(instrument->port->hostName, appsNew->portArray[count - 1].hostName);
  322.           instrument->port->portNumber = appsNew->portArray[count - 1].portNumber;
  323.           xv_set(instrument->editInfo->HostnameText,            /* Set the hostname on the pop-up window */
  324.              PANEL_LABEL_STRING, instrument->port->hostName, NULL);
  325.           instrument->icon = (Pixmap) xv_get(OpenAppsFindIcon(instrument), /* Get the pixmap image of the icon */
  326.                          SERVER_IMAGE_PIXMAP);
  327.           tlFrame->chosenApp = i;
  328.           HideApplicationHandler(tlFrame->TimeLine_window->appButton, MENU_NOTIFY); /* Iconify the application */
  329.           tlFrame->chosenApp = -1;
  330.         }
  331.       }
  332.       if (result == -1 || load == 1) 
  333.       {      
  334.     xv_set(instrument->editInfo->MuteChoice, PANEL_VALUE, 1, NULL); /* Mute the app */
  335.     xv_set(instrument->editInfo->MuteChoice, PANEL_INACTIVE, TRUE, NULL);
  336.     strcpy(instrument->port->hostName, "App not open");
  337.     xv_set(instrument->editInfo->HostnameText,            /* Set the hostname on the pop-up window */
  338.            PANEL_LABEL_STRING, instrument->port->hostName, NULL);
  339.       }
  340.     }
  341.     instrument = instrument->next;
  342.   }
  343.   if (load == 1)                            /* Check if we want to add the unassigned apps to the instrument list */
  344.   {
  345.     for (i = 0; i < appsOpen->numberOfPorts; i++)            /* Add the remaining unassigned ports (which are not TimeLine apps to  */
  346.     {                                    /* the instrument list */
  347.       if (strcmp(appsOpen->portArray[i].appName, TimeLineName) != 0 && /* Check that the application is not a TimeLine Editor */
  348.       portUsed[i] == 0)                        /* Check that the port is not already assigned */
  349.     AddInstrument(appsOpen->portArray+i, tlFrame);
  350.     }
  351.   }
  352.   free (portUsed);
  353.   DestroyPortArray(appsNew);
  354.   DestroyPortArray(appsOpen);
  355. }
  356.  
  357. /*
  358.  * This function takes an instrument.  
  359.  * First, it tries to ask the application to send the icon bits over the network.
  360.  * If this fails, it gets the name of the application and attempts to find the bitmap icon file for
  361.  * it in the graphics directory.  If successful, it converts this file into a server bitmap image and returns it.
  362.  * Called by InstrumentDrawIcon (instrument.c)
  363.  */
  364. Server_image OpenAppsFindIcon(instrument)
  365.      Instrument *instrument;
  366. {
  367.   Server_image icon;
  368.   IconData *appIcon;
  369.   Sender *sender;
  370.   int result;
  371.  
  372.   appIcon = (IconData *) malloc (sizeof(IconData));
  373.   appIcon->iconData = (char *) 0;
  374.   appIcon->dataLength = 0;
  375.   sender = NULL;
  376.   if (strcmp(instrument->port->hostName, "App not open") != 0) 
  377.     sender = NewSender(instrument->port);                /* Check if the application is still alive */
  378.   if (sender != NULL) 
  379.   {
  380.     result = SenderGetAppIcon(instrument->sender, &(appIcon));        /* If the get app icon fails, return the unknown icon */
  381.     if (result == -1) 
  382.       return unknownIcon;
  383.     DestroySender(sender);
  384.   }
  385.   if (appIcon->dataLength > 0) 
  386.     icon = (Server_image) xv_create(NULL, SERVER_IMAGE,
  387.                     SERVER_IMAGE_BITS, appIcon->iconData,
  388.                     SERVER_IMAGE_DEPTH, 1,
  389.                     XV_WIDTH, 64,
  390.                     XV_HEIGHT, 64,
  391.                     NULL);
  392.   else 
  393.     icon = unknownIcon;
  394.   return icon;
  395. }
  396.  
  397. /*
  398.  * Menu handler for `AppMenu (Update Applications List)'.
  399.  * This function will update the instrument list with a list from the port manager.  It will attempt to merge the two list together (in OpenAppsInitialize).
  400.  * The canvas height is set according to the number of open applications and the repaint canvas procedure is called to show all the new
  401.  * applications.
  402.  */
  403. Menu_item UpdateAppsHandler(item, op)
  404.      Menu_item    item;
  405.      Menu_generate    op;
  406. {
  407.   TimeLineFramePtr tlFrame;
  408.   TimeLine_window_objects    *ip = (TimeLine_window_objects *) xv_get(item, XV_KEY_DATA, INSTANCE);
  409.  
  410.   tlFrame = TimeLineWindow[xv_get(ip->controls, PANEL_CLIENT_DATA)];
  411.   switch (op) 
  412.   {
  413.    case MENU_DISPLAY:
  414.     break;
  415.    case MENU_DISPLAY_DONE:
  416.     break;
  417.    case MENU_NOTIFY:
  418.     OpenAppsInitialize(tlFrame, 1);                    /* Get the new list of open applications from the Port Manager */
  419.     SetCanvasHeight(tlFrame);
  420.     AppCanvasRepaintHandler(tlFrame->TimeLine_window->AppCanvas, tlFrame->paintWinApp, 
  421.                 tlFrame->dpyApp, tlFrame->xidApp, NULL);
  422.     break;
  423.    case MENU_NOTIFY_DONE:
  424.     break;
  425.   }
  426.   return item;
  427. }
  428.  
  429. /*
  430.  * Menu handler for `AppMenu (Delete an application)'.
  431.  * This function will delete an instrument from the instrument.  The instrument should have been selected on the AppCanvas, or else no action is taken.
  432.  * First, check to see which instrument is to be deleted.
  433.  * Next, decrement the number of instruments counters.
  434.  * Update the positions of the instruments following the deleted one on the list, so that they are shifted up by 1 in terms of their relative position.
  435.  * Free the space allocated to the deleted instrument.
  436.  * Set the new canvas height and redraw the canvas.
  437.  */
  438. Menu_item DeleteAppHandler(item, op)
  439.      Menu_item        item;
  440.      Menu_generate    op;
  441. {
  442.   Instrument *instrument, *prevInst;
  443.   Instrument *nextInst;
  444.   Note *note, *nextNote;
  445.   Sender *sender;
  446.   TimeLineFramePtr tlFrame;
  447.   TimeLine_window_objects    *ip = (TimeLine_window_objects *) xv_get(item, XV_KEY_DATA, INSTANCE);
  448.  
  449.   tlFrame = TimeLineWindow[xv_get(ip->controls, PANEL_CLIENT_DATA)];
  450.   switch (op) 
  451.   {
  452.    case MENU_DISPLAY:
  453.     break;
  454.    case MENU_DISPLAY_DONE:
  455.     break;
  456.    case MENU_NOTIFY:
  457.     if (tlFrame->chosenApp >= 0) 
  458.     {
  459.       instrument = (Instrument *) FindInstrument (tlFrame->chosenApp, tlFrame); /* Instrument to be deleted */
  460.       if (instrument == NULL) 
  461.     return item;
  462.       nextInst = instrument->next;
  463.       if (tlFrame->chosenApp == 0) 
  464.     tlFrame->instHead = tlFrame->instHead->next;
  465.       else 
  466.       {
  467.     prevInst = (Instrument *) FindInstrument (tlFrame->chosenApp - 1, tlFrame); /* The instrument before the one to be deleted */
  468.     prevInst->next = instrument->next;
  469.       }
  470.       tlFrame->numberOfApps --;                        /* Decrement the total number of applications count */
  471.       while (nextInst != NULL)                        /* Update the positions of the instruments following the deleted instrument */
  472.       {                                    /* (Shift up by 1) */
  473.     nextInst->relativePosition --;
  474.     xv_set(nextInst->editInfo->NoteInfoList,            /* Attach the instrument's relative position as the PANEL_CLIENT_DATA. */
  475.            PANEL_CLIENT_DATA, nextInst->relativePosition,        /* Lets the program know which instrument the panel belongs to. */
  476.            NULL);
  477.     nextInst->cableStart = (IconHeight + IconGap) * nextInst->relativePosition + FirstCableYPosition;
  478.     nextInst = nextInst->next;
  479.       }
  480.       note = instrument->firstNote;                    /* Free the space allocated to the deleted instrument and its notes */
  481.       nextNote = instrument->firstNote;
  482.       while (nextNote != NULL)                        /* Free the notes */
  483.       {
  484.     nextNote = note->next;
  485.     free (note);
  486.     note = nextNote;
  487.       }
  488.       xv_destroy_safe(instrument->editInfo->EditInfoWindow);        /* Free the edit pop-up window */
  489.       if (strcmp(instrument->port->hostName, "App not open") != 0) 
  490.       {
  491.     sender = NewSender(instrument->port);
  492.     if (sender != NULL) 
  493.     {
  494.       DestroySender(instrument->sender);
  495.       DestroySender(sender);
  496.     }
  497.       }
  498.       free (instrument);
  499.       tlFrame->chosenApp = -1;
  500.       SetCanvasHeight(tlFrame);                        /* Set the new canvas height and redraw the canvas */
  501.       AppCanvasRepaintHandler(tlFrame->TimeLine_window->AppCanvas, tlFrame->paintWinApp, 
  502.                   tlFrame->dpyApp, tlFrame->xidApp, NULL);
  503.       ScrollToFirstQuarter(tlFrame, 0, 1);
  504.     }
  505.     break;
  506.    case MENU_NOTIFY_DONE:
  507.     break;
  508.   }
  509.   return item;
  510. }
  511.  
  512. /*
  513.  * Menu handler for `AppMenu (Show edit info for an application)'.
  514.  * This function displays the instrument info pop-up window.
  515.  */
  516. Menu_item ShowEditInfoHandler(item, op)
  517.      Menu_item    item;
  518.      Menu_generate    op;
  519. {
  520.   Instrument *currentInst;
  521.   TimeLineFramePtr tlFrame;
  522.   TimeLine_window_objects    *ip = (TimeLine_window_objects *) xv_get(item, XV_KEY_DATA, INSTANCE);
  523.  
  524.   tlFrame = TimeLineWindow[xv_get(ip->controls, PANEL_CLIENT_DATA)];
  525.   switch (op) 
  526.   {
  527.    case MENU_DISPLAY:
  528.     break;
  529.    case MENU_DISPLAY_DONE:
  530.     break;
  531.    case MENU_NOTIFY:
  532.     if (tlFrame->chosenApp >= 0)                    /* Check if an application is selected */
  533.     {
  534.       currentInst = (Instrument *) FindInstrument(tlFrame->chosenApp,
  535.                           tlFrame);        /* Get pointer to the currently chosen instrument node */
  536.       ShowInfoWindow(currentInst, tlFrame);                /* Show the pop up info window */
  537.     }
  538.     break;
  539.    case MENU_NOTIFY_DONE:
  540.     break;
  541.   }
  542.   return item;
  543. }
  544.  
  545. /*
  546.  * Menu handler for `AppMenu (Hide application)'.
  547.  * This function will send the SenderHideApplication message to the selected application, which will then take the appropriate action to hide itself.
  548.  * Hiding means iconifying here.
  549.  */
  550. Menu_item HideApplicationHandler(item, op)
  551.      Menu_item    item;
  552.      Menu_generate    op;
  553. {
  554.   Instrument *instrument;
  555.   TimeLineFramePtr tlFrame;
  556.   TimeLine_window_objects    *ip = (TimeLine_window_objects *) xv_get(item, XV_KEY_DATA, INSTANCE);
  557.   
  558.   tlFrame = TimeLineWindow[xv_get(ip->controls, PANEL_CLIENT_DATA)];
  559.   switch (op) 
  560.   {
  561.    case MENU_DISPLAY:
  562.     break;
  563.    case MENU_DISPLAY_DONE:
  564.     break;
  565.    case MENU_NOTIFY:
  566.     if (tlFrame->chosenApp >= 0) 
  567.     {
  568.       instrument = (Instrument *) FindInstrument(tlFrame->chosenApp, tlFrame);
  569.       if (instrument == NULL) 
  570.     return item;
  571.       if (CheckAppOpen(tlFrame, instrument, 2) == Error)
  572.     return item;
  573.       SenderHideApplication(instrument->sender);
  574.     }
  575.     break;
  576.    case MENU_NOTIFY_DONE:
  577.     break;
  578.   }
  579.   return item;
  580. }
  581.  
  582. /*
  583.  * Menu handler for `AppMenu (Show application)'.
  584.  * This function will send the SenderShowApplication message to the selected application, which will then take the appropriate action to show itself.
  585.  */
  586. Menu_item ShowApplicationHandler(item, op)
  587.     Menu_item    item;
  588.     Menu_generate    op;
  589. {
  590.   Instrument *instrument;
  591.   TimeLineFramePtr tlFrame;
  592.   TimeLine_window_objects    *ip = (TimeLine_window_objects *) xv_get(item, XV_KEY_DATA, INSTANCE);
  593.  
  594.   tlFrame = TimeLineWindow[xv_get(ip->controls, PANEL_CLIENT_DATA)];
  595.   switch (op) 
  596.   {
  597.    case MENU_DISPLAY:
  598.     break;
  599.    case MENU_DISPLAY_DONE:
  600.     break;
  601.    case MENU_NOTIFY:
  602.     if (tlFrame->chosenApp >= 0) 
  603.     {
  604.       instrument = (Instrument *) FindInstrument(tlFrame->chosenApp, tlFrame);
  605.       if (instrument == NULL) 
  606.     return item;
  607.       if (CheckAppOpen(tlFrame, instrument, 2) == Error)
  608.     return item;
  609.       SenderShowApplication(instrument->sender);
  610.     }
  611.     break;
  612.    case MENU_NOTIFY_DONE:
  613.     break;
  614.   }
  615.   return item;
  616. }
  617.  
  618.